﻿using System.ComponentModel;
using System.Reflection;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace QW.Found.Filter
{
    /// <summary>
    /// Swagger架构处理器
    /// </summary>
    public class SwaggerSchemaFilter : ISchemaFilter
    {
        /// <summary>
        /// 过滤器
        /// </summary>
        public void Apply(OpenApiSchema schema, SchemaFilterContext context)
        {
            if (context.Type.IsEnum)
            {
                #region 设置枚举的描述
                List<string> titleItems = new List<string>();
                foreach (var e in Enum.GetValues(context.Type))
                {
                    var value = Enum.Parse(context.Type, e.ToString());
                    var desc = GetDescription(context.Type, value);

                    if (string.IsNullOrEmpty(desc))
                        titleItems.Add($"{(int)e}={Enum.GetName(context.Type, value)}");
                    else
                        titleItems.Add($"{(int)e}={Enum.GetName(context.Type, value)},{desc}");
                }
                schema.Description = string.Join("；", titleItems);
                #endregion
            }
            else
            {
                #region 移除设置了SwaggerIgnoreAttribute特性的属性
                //foreach (var propertyName in context.Type.GetProperties().Where(ii => ii.GetCustomAttribute<SwaggerIgnoreAttribute>() != null).Select(ii => ii.Name))
                //    schema.Properties.Remove(propertyName);
                #endregion
            }
        }

        private static string GetDescription(Type t, object value)
        {
            foreach (MemberInfo mInfo in t.GetMembers())
            {
                if (mInfo.Name == t.GetEnumName(value))
                {
                    foreach (Attribute attr in Attribute.GetCustomAttributes(mInfo))
                    {
                        if (attr.GetType() == typeof(DescriptionAttribute))
                        {
                            return ((DescriptionAttribute)attr).Description;
                        }
                    }
                }
            }
            return string.Empty;
        }
    }
}
